/*
 * FileName: who1.c
 * Author  : mofei
 * History : 2014-07-22
 * Desc    : a first version of the who program
 *           open, read UTMP file, and show results.
 */

#include <stdio.h>
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

#define SHOWHOST             /* include remote machine on ouput */

void show_time(long);
void show_info(struct utmp *);

int main(int argc, char *argv[]) {
    struct utmp current_record;        /* read info into here */
    int         utmpfd;                /* read from this descriptor */
    int         reclen = sizeof(current_record);

    if((argc == 1) | ((argc == 3) && !strcmp(argv[1], "am") && !strcmp(argv[2], "i"))) {
        if((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1) {
            perror(UTMP_FILE);              /* UTMP_FILE is in utmp.h */
            return -1;
        }
    } else
        return -1;

    while(read(utmpfd, &current_record, reclen) == reclen)
        show_info(&current_record);
    close(utmpfd);
    
    return 0;
}

/*
 * show_info()
 * displays contents of the utmp struct in human readable
 * from *note* these sizes should not be hardwired
 */
void show_info(struct utmp *utbufp) {
    if(utbufp->ut_type != USER_PROCESS)
        return;

    printf("%-8.8s", utbufp->ut_name);     /* the logname */
    printf(" ");;
    printf("%-8.8s", utbufp->ut_line);     /* the tty */
    printf(" ");
    //printf("%10d", utbufp->ut_time);       /* login time */
    show_time(utbufp->ut_time);
    printf(" ");
#ifdef SHOWHOST
    if(utbufp->ut_host[0] != '\0')
        printf("(%s)", utbufp->ut_host);       /* the host */
#endif
    printf("\n");
}

/* show_time():
 * displays time in a format fit for human consumption
 * uses ctime build a string then picks parts out of it
 * Not: %12.12s prints a string 12 chars wide and LIMITS
 * it to 12 chars
 */
void show_time(long timeval) {
    char *cp;                 /* to hold address of time */
    cp = ctime(&timeval);     /* convert time to string */
    printf("%12.12s", cp+4);  /* pick 12 chars from pos 4 */
}
